feat: implement Beta.2.1 unified Router and standalone Element tooling - #1343
feat: implement Beta.2.1 unified Router and standalone Element tooling#1343SisyphusZheng wants to merge 24 commits into
Conversation
|
APIError: Insufficient Balance |
|
Maintainer-approved Beta.2.x plan updated on 2026-09-08 in planning PR #1342, ADR-0152, VERSION_PLAN, 15 existing issues and Project 3.
The review comment #1343 (comment) says APIError: Insufficient Balance. The review workflow's SUCCESS is not a completed review. #1332 explicitly owns service recovery and failure propagation as an immediate merge prerequisite, not deferred cleanup. No provider/model or billing changes have been made. #1343 remains incomplete: SSG output/navigation findings, fork migration/memory baselines, actual review, final-SHA CI and fresh verifier evidence are outstanding. Confirming #1342 ancestry is not a claim of baseline CI success. These planning updates do not repair product code or authorize release. Consume the updated #1342 planning contract before continuing implementation. |
…roved contracts)
Consumes planning HEAD dcfa2ee. toSSG discovery via app.routes yields nothing behind app.all('*', dispatcher) (middleware arity filtered); project eligible static pages (rendering!=dynamic, non-dynamic) for discovery only, render through real app.fetch/request. Preserve host routes, exclude wildcard. Align default mock dispatcher with routeInfo. Fixes RED ssg-render record test; www build 150 pages, /,/docs,sitemap present.
…oller POST with formData leaves to browser/server before pending/intercept; fragment-only and reload default browser-owned in history mode, hash semantics separate. Each spa mount gets a fresh AbortController; stale loader/action results never commit. Tests: native ownership unit (POST/fragment/reload/GET), mount fresh signal (mount/dispose/remount, direct remount stale, action signal), 3-browser POST/fragment/reload proof + existing nav regression.
The ADR-0152 chain (beta.2.1-beta.2.3, then 1.0.0-alpha.1) is planned, not retired: derive exemptions from lib/version.ts checkpoint/stage successors instead of banning every non-current prerelease. Unapproved prereleases (beta.3, historical 0.44.0-alpha.N) stay forbidden; the alpha.N shorthand no longer matches inside an exempted full version. Fixes the www build artifact-truth failure introduced by consuming planning HEAD dcfa2ee.
The review action posts provider errors as PR comments while exiting 0, so the green wrapper was not review evidence (observed on #1343: APIError Insufficient Balance). A Deno gate now verifies the step outcome and the run-attributed review comment, matching structural provider/API error signatures across billing, rate-limit, auth, availability, timeout and model categories; absence of evidence fails closed. Provider restoration itself needs external billing action and stays a merge prerequisite.
…patch fullstack:boundary-check sliced per-route app.get/app.post registrations; the unified dispatcher keeps per-record handlers in the generated __pageHandlers method table. Slice that table instead, preserving the ADR-0121 no-store assertions (non-vacuous GET presence, baseline emission, public-cache rejection). Drop the duplicate route.path from the file-routed configuration examples: file paths own generated route paths (ADR-0152). Wire the standalone Element packed-consumer proof as a deno task.
Deploying openelement with
|
| Latest commit: |
95c3060
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://94764ac4.lessjs.pages.dev |
| Branch Preview URL: | https://codex-beta2-1-router-core.lessjs.pages.dev |
|
APIError: Insufficient Balance |
The planning rewrite of roadmap.tsx quotes object keys ('stamp': …); the
AST extractor only accepted identifiers, so no CURRENT entry was found.
Accept string-literal keys as well.
|
APIError: Insufficient Balance |
open-element/url-pattern-list @00bface carries the qualified implementation, Node-native differential tests and the four construction/hit/miss/memory benchmarks. The embedded copy remains the production matcher until the separately authorized npm publish unblocks consumption (#1324).
|
APIError: Insufficient Balance |
…ion API history.replaceState fires a navigate event (navigationType replace) when the Navigation API is active; the router intercepted its own guard-veto restore as a fresh navigation and emitted a spurious change notification after a blocked back/forward walk (3-browser router-guard e2e failure). Mark the restore's replace navigation and intercept it without rematch/notify; an unintercepted marked replace races the in-flight traverse and never lands. The e2e probe now observes Navigation API navigations (navigation.navigate/updateCurrentEntry replace reporting), which the legacy history.pushState/replaceState spies cannot see. Also: point the critical-path gate at the renamed path-param decoding evidence, and regenerate the content graph after the guide edits.
|
APIError: Insufficient Balance |
The review job is supplemental and must not block CI. The outcome gate still detects a non-executed or provider-errored review (step outcome plus run-attributed comment classification) and surfaces it as a warning annotation instead of a red check — visible, never silently counted as review evidence.
|
APIError: Insufficient Balance |
pattern becomes RoutePatternComponents (Omit<URLPatternInit, 'pathname'>): the type omits pathname and the constructor rejects it at runtime for JS callers, so a record can never fork pathname identity between route metadata and the matcher. Full-URL components (hostname/protocol/…) are unaffected; Framework Mode records never carried a second pathname.
router.searchParams returned the router's live internal URLSearchParams; a loader/action (or any reader) calling .set() would rewrite canonical router state without touching the address bar. The getter now returns a fresh copy per read, so loader and action contexts each get their own mutable copy. Tests: getter isolation (state, address bar, subsequent navigations) and a loader mutating its copy without polluting the router.
Audit of all consumers (version anchors, docs truth, strategic docs, release state) shows only channel classification reads it; full checkpoint identity already flows through identifiers/compareVersions/next helpers. The field comment now says so explicitly.
The supplemental review job is non-blocking; missing/errored reviews are detected and reported as warnings, never counted as evidence. VERSION_PLAN, ADR-0152 and the issue map previously demanded a fail-closed merge prerequisite; all three now state one policy.
|
APIError: Insufficient Balance |
|
APIError: Insufficient Balance |
…tePatternComponents The RouteRecord.pattern type narrowing drifts the public shape hash and generated API reference; both artifacts are regenerated, not hand-edited. Also drop the provider name from VERSION_PLAN (role-neutral docs gate).
|
APIError: Insufficient Balance |
Beta.2.1: Router/core convergence, standalone Element, prerelease semantics
Target
Beta.2.1 implementation for #1320, #1323, #1324, #1325 and #1338, under ADR-0152 and
docs/current/VERSION_PLAN.md. This branch contains the approved planning content of#1342 (still OPEN) through merge
d16f7223(planning SHAdcfa2ee5); per thegovernance order, #1342 merges first, then this PR is refreshed onto the new
dev.The comparison includes that prerequisite plan until then.
Architecture
pathis the only pathname truth;pattern(RoutePatternComponents) carries onlynon-pathname URL components and a runtime
pathnameis rejected, not silently honored.URLSearchParamsstay separate;router.searchParamshands outper-reader snapshots so loaders/actions cannot mutate router state.
the real dispatcher. Browser navigation keeps POST/reload/fragment/download/cross-origin
browser-owned; every mount gets a fresh AbortController; guard vetoes restore via a
marked replace navigation that the router never re-intercepts.
What Changed
to the URL winner; explicit HEAD wins, otherwise HEAD falls back to GET inside the
winner with an empty body.
(host routes preserved, wildcard excluded); the www build emits 150 static pages again.
signal per mount; stale loader/action/guard results never commit.
@openelement/adapter-vite/elementexposes the existing private compiler plugin forstandalone Element tooling; packed App/UI edges are optional peers.
(
beta.2 → beta.2.1 → beta.2.2 → beta.2.3 → 1.0.0-alpha.1by explicit product-stagetransition);
prereleaseNumberis documented as a legacy channel-level field.__pageHandlersmethod table (no-store assertions preserved, non-vacuous); www truthgates admit the approved planned version chain and quoted roadmap keys; the critical-path
gate tracks the renamed path-param evidence; the supplemental AI-review job reports a
missing/errored review as a warning instead of masquerading as green evidence
(non-blocking per the 2026-09-09 maintainer decision).
What Was Removed
method-dependent winner fallback; the duplicate
route.pathdeclaration in generatedrecords; the per-page Hono winner/405 paths;
pattern.pathnameas an override channel.Fork / Dependency Boundary
open-element/url-pattern-list@00bface02e3117222dea9c620a63792545f04c13(on top ofupstream v0.5.0
4911e649, history and MIT attribution preserved) carries the qualifiedimplementation: 109/109 Node-native tests after a clean
npm ci, ordered-linear-oracledifferential coverage on native and polyfill constructors with seeded/reduced failures,
and construction/hit/miss/memory benchmarks in its
BENCHMARKS.md(GC-controlled,retained vs transient; static-only 5000-pattern hit 0.0057ms vs linear 2.82ms; the
all-conservative scenario honestly degrades to linear). Two genuine upstream bugs have
recipient-native reproductions drafted in the fork's
docs/upstream-issues.md(unreported; upstream responsiveness is not an OE gate).
@open-element/url-pattern-list@0.6.0to npm is aseparate release authorization this task does not have. Until it lands, the embedded
production copy at
packages/app/src/internal/router/url-pattern-list/remains thetransitional matcher (its PROVENANCE.md records the fork as its maintenance home and
retirement condition). Switch rehearsal: RouteTable ran the fork's packed 0.6.0 build
through the route-resolution/router-http/client-router/route-pattern suites — 41/41 pass;
the post-publish switch is a small, rehearsed diff (constructor entries →
addPattern).Standalone Element
deno task consumer:packaged-elementproves author → compile → pack → install outside theworkspace → plain HTML → real registration/attribute/event updates in Chromium 147,
Firefox 148 and WebKit 26.4, with no Router/App/UI installed, no workspace aliases, a clean
browser module graph, 32 reachable declaration modules checked, and authored source maps
retained. The compiler stays private; this is a tooling subpath, not a public compiler API.
Version Semantics
Lossless multi-identifier parsing/comparison; checkpoint succession is explicit
(
nextCheckpointVersion), product-stage transition is explicit (1.0.0-alpha.1);historical internal
0.44.0-alpha.0–10stay unpublishable; channels map to dist-tags.beta.3ordering is legal SemVer but not an approved checkpoint (www truth gate rejects it).No package version was bumped.
Validation — exact final SHA
95c30600Local (macOS arm64, Deno 2.9.0 / Node 24.18.0; Chromium 147 / Firefox 148 / WebKit 26.4):
deno task test: 1920 passed (105 steps) + supabase starter 150 passed, 0 failed.deno task build: full chain green; 150 static pages incl./,/docs,sitemap.xml(146 URLs); artifact-truth and link checks pass.
deno fmt --check,deno lint,deno task typecheck,arch:check,graph:check,workflow:check,docs:truth,actions:check-pins: all pass.171 + 171 passed; Deno-driven three-browser POST/fragment/reload and packed-Element
proofs pass.
consumer:packaged,consumer:packaged-ui,consumer:packaged-elementpassagainst freshly packed tarballs.
CI on this exact SHA: autoflow-ci PASS (16m36s full matrix: build, coverage,
critical-paths, chromium/firefox/webkit e2e, request-time/ui-dogfood fixture gates,
starter smoke, static-output freeze, packed consumers), pr-full-ci-evidence PASS,
Cloudflare Pages PASS, dist/server Node 20 + Node 24 + Bun smoke PASS, CodeQL /
dependency-review / workspace-qualification / Analyze PASS. The supplemental
reviewjob is green with a warning annotation (no review executed — see below).
Known Non-blocking External Conditions
APIError: Insufficient Balance(external billing action, [beta.2.3] Simplify CI and AutoFlow around final semantic responsibilities #1332). The review job reportsthis as a warning and stays green by maintainer decision; this run contributes zero
independent review evidence. Required CI gates, human review and the fresh verifier
remain the real gates.
dev, is the required governance order.Release Impact
None: no version bump, tag, npm publish, deployment, merge or issue closure. Examples stay
frozen. Release state and evidence files are unchanged; Beta.2.1 publication remains a
separately gated decision.